/* 
 * Copyright (c) 2012 JSquirrelEngine
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in 
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 */

package org.jsquirrel.geometry.impl;

import org.jsquirrel.geometry.Polygon;
import org.jsquirrel.geometry.VertexIterator;
import org.jsquirrel.math.F2Vector;


/**
 * Implementation of the Polygon class in which the vertices are stored as an array of F2Vector.
 * 
 * @author Juan David Adarve Bermudez
 *
 */
public class ArrayPolygon extends Polygon {
	
	//*********************************************************************************************
	// INSTANCE ATTRIBUTES
	//*********************************************************************************************
	
	/**
	 * Array to store the vertices of the polygon. Its visibility	
	 * is default in order to be visible to the ArrayPolygonVertexIterator
	 * directly.
	 */
	F2Vector vertices[];
	
	/**
	 * counts the number of vertices so far stored in the array
	 */
	int vertexCount;
	
	
	//*********************************************************************************************
	// CONSTRUCTOR
	//*********************************************************************************************
	
	/**
	 * Default constructor, the vertices array is set to null
	 */
	public ArrayPolygon() {
		 vertices = null;
		 vertexCount = 0;
	}
	
	/**
	 * Creates a new instance with a given capacity for the vertex array. The capacity may grow by
	 * adding new vertices.
	 * 
	 * @param numVertices
	 */
	public ArrayPolygon(int numVertices) {
		
		if(numVertices <= 0) {
			// add log entry
			throw new IllegalArgumentException("The number of vertices must be greater than zero");
		}
		
		vertices = new F2Vector[numVertices];
		
		// even if the vertex information contained at this point is not
		// necessary valid, yet the polygon has allocated numVertices F2Vector
		vertexCount = numVertices;
		
		// instantiates each of the vertices
		for(int i = 0; i < vertices.length; i ++) {
			vertices[i] = new F2Vector();
		}
	}
	

	@Override
	protected void addVertexImpl(F2Vector vertex) {
		
		if(vertices == null) {
			vertices = new F2Vector[1];
		}
		// if the capacity of the array has been completed
		else if(vertexCount == vertices.length) {
			
			F2Vector aux[] = new F2Vector[vertices.length + 1];
			for(int i = 0; i < vertices.length; i ++) {
				aux[i] = new F2Vector(vertices[i]);
			}
			
			vertices = null;
			vertices = aux;
		}
				
		vertices[vertexCount] = new F2Vector(vertex);
		vertexCount ++;
	}
	
	@Override
	protected void addVertexImpl(float x, float y) {
		
		if(vertices == null) {
			vertices = new F2Vector[1];
		}
		// if the capacity of the array has been completed, the capacity is enlarged by one
		else if(vertexCount == vertices.length) {
			
			F2Vector aux[] = new F2Vector[vertices.length + 1];
			for(int i = 0; i < vertices.length; i ++) {
				aux[i] = new F2Vector(vertices[i]);
			}
			
			vertices = null;
			vertices = aux;
		}
		
		vertices[vertexCount] = new F2Vector(x, y);
		vertexCount ++;
	}

	@Override
	public int length() {
		return vertexCount;
	}

	@Override
	public VertexIterator getIterator() {
		return new ArrayPolygonVertexIterator(this);
	}	
}


/**
 * VertexIterator implementation for ArrayPolygon
 * 
 * @author Juan David Adarve Bermudez
 *
 */
class ArrayPolygonVertexIterator extends VertexIterator {
	
	//*********************************
	// INSTANCE ATTRIBUTES
	//*********************************	
	private int index;
	
	private ArrayPolygon polygon;
	
	
	//*********************************
	// CONSTRUCTOR
	//*********************************
	public ArrayPolygonVertexIterator(ArrayPolygon polygon) {
		this.polygon = polygon;
		index = -1;
	}

	@Override
	public boolean hasNext() {
		return index + 1 < polygon.vertexCount;
	}

	@Override
	public F2Vector next() {
		index ++;
		return polygon.vertices[index];
	}

	@Override
	public void remove() {
		// TODO: add log entry
		throw new UnsupportedOperationException("ArrayPolygonVertexIterator.remove(): unsupported operation");
	}

}